/*
	The Raja Toolkit.
	Copyright (C) 2011 Raja-Toolkit Foundation

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 3.0 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/


#ifndef RAJA_TYPES
#define RAJA_TYPES

#include <vector>
#include <string>
#include <map>
#include <list>
#include <limits>
#include <cmath>
#include <iostream>
#include <cassert>
#include <cstring>
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp>

#ifndef offsetof
#define offsetof(st, m) \
	((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
#endif

namespace raja
{
typedef unsigned char		uint8;
typedef unsigned short		uint16;
typedef unsigned int		uint32;
typedef unsigned long int	uint64;

typedef signed char			sint8;
typedef signed short		sint16;
typedef signed int			sint32;
typedef signed long int		sint64;

typedef float				real32;
typedef double				real64;

// change this as it suits you
typedef real32				real;
typedef sint32				sint;
typedef uint32				uint;

///
/// get the half of value
///
template<typename T> T		half(const T& t);

template<> inline uint8		half<uint8>(const uint8& u)			{	return (u >> 1); }
template<> inline uint16	half<uint16>(const uint16& u)		{	return (u >> 1); }
template<> inline uint32	half<uint32>(const uint32& u)		{	return (u >> 1); }
template<> inline uint64	half<uint64>(const uint64& u)		{	return (u >> 1); }

template<> inline sint8		half<sint8>(const sint8& u)			{	return (u >> 1); }
template<> inline sint16	half<sint16>(const sint16& u)		{	return (u >> 1); }
template<> inline sint32	half<sint32>(const sint32& u)		{	return (u >> 1); }
template<> inline sint64	half<sint64>(const sint64& u)		{	return (u >> 1); }

template<> inline real32	half<real32>(const real32& u)		{	return (u * 0.5f); }
template<> inline real64	half<real64>(const real64& u)		{	return (u * 0.5); }



///
/// @brief element array
///
/// Needs element size for the initialization. It is like std::vector, but allow allocation
/// for dynamic runtime size elements.
///
struct element_array
{
	element_array(uint32 elem_size);
	~element_array();

	void					resize(uint32 count);

	void*					push_back(const void* elem);
	void*					pop_back();

	const void*				operator[](uint32 idx) const;
	void*					operator[](uint32 idx);
	uint32					get_count() const;

	void*					push_multiple(const void* elems, uint32 count);

private:
	element_array() : __elem_size(0), __data(0), __count(0), __real_size(0)
	{
	}

	uint32					__elem_size;
	void*					__data;
	uint32					__count;
	uint32					__real_size;
};

}	// namespace raja

#endif // RAJA_TYPES
